package name.marz.to.go.ahg;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.logging.Level;
import java.util.logging.Logger;

import name.marz.to.go.ahg.common.cli.OutDirOption;
import name.marz.to.go.ahg.common.cli.PasswordOption;
import name.marz.to.go.ahg.common.util.HttpUtil;
import name.marz.to.go.ahg.common.util.LogUtil;
import name.marz.to.go.ahg.core.AbstractAutoGetterMain;
import name.marz.to.go.ahg.core.AutoGetterHttpClient;
import name.marz.to.go.ahg.core.exception.UserProcessException;
import name.marz.to.go.ahg.core.executer.AbstractLoginExecuter;
import name.marz.to.go.ahg.core.executer.DocumentGetExecuter;
import name.marz.to.go.ahg.core.executer.FileDownloadExecuter;
import name.marz.to.go.ahg.saison.executer.SaisonCSVDownloader;
import name.marz.to.go.ahg.saison.executer.SaisonDealDetailExecuter;
import name.marz.to.go.ahg.saison.executer.SaisonLoginExecuter;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;


public class SaisonGetMain extends AbstractAutoGetterMain {
	private static final Logger log = Logger.getLogger(SaisonGetMain.class.getName());
	private static final String DEFAULT_MEISAI_DIRNAME=".";
	
	AutoGetterHttpClient client = new AutoGetterHttpClient();
	HttpContext context = new BasicHttpContext();
	
	String userId;
	private String password;
	private File outDir;
	
	private URI baseUri;
	/**
	 * 
	 */
	public SaisonGetMain() {
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SaisonGetMain main = new SaisonGetMain();
		main.Main(args);
	}
	
	/* (non-Javadoc)
	 * @see name.marz.to.go.ahg.core.AbstractMain#ready()
	 */
	@Override
	protected void ready() throws Exception {
		super.ready();
		baseUri = HttpUtil.createURISafety("https://netanswerplus.saisoncard.co.jp/WebPc/welcomeSCR.do");
	}
	
	@Override
	public Document goTopPage() throws ClientProtocolException, IOException,
			UserProcessException {
		Document doc;
		doc = new DocumentGetExecuter(baseUri, client,"TOP").execute();
		LogUtil.log(Level.FINE, client.getCookieStore().getCookies());
		LogUtil.log(Level.FINE, HttpUtil.getParametersFromInputTags(doc),"top page params");
		return doc;
	}

	@Override
	public Document doLogin(Document doc) throws ClientProtocolException,
			IOException, UserProcessException {
		AbstractLoginExecuter le = new SaisonLoginExecuter(baseUri, client, new String[] { userId },password,doc);
		doc = le.execute();
		log.finer("login response source="+doc.html());
		return doc;
	}

	@Override
	public Document goDownloadPage(Document doc)
			throws ClientProtocolException, IOException, UserProcessException {
		log.info("利用明細確認ページへ遷移中");
		Elements e = doc.getElementsByAttributeValue("alt", "利用明細確認");
		log.fine(e.first().parent().parent().html());
		log.fine(e.first().parent().tagName());
		log.fine(e.first().parent().attr("href"));
		final Document dealDoc = doc;
		DocumentGetExecuter de = new SaisonDealDetailExecuter(baseUri, client, dealDoc);
		doc = de.execute();
		return doc;
	}

	@Override
	public File doDownload(Document doc) throws ClientProtocolException,
			IOException, UserProcessException {
		log.fine("dl a tag="+doc.getElementsByAttributeValue("alt", "CSVダウンロード")
								.first().parent().outerHtml());
		FileDownloadExecuter fde = new SaisonCSVDownloader(baseUri, client, outDir, doc);
		return fde.execute();
	}

	@Override
	public void doLogout(Document doc) throws ClientProtocolException,
			IOException, UserProcessException {
		// ログアウトタグからログアウト用URLを取り出す
		final String LOGOUT_ID="logOut";
		Element e = doc.getElementById(LOGOUT_ID);
		if ( e == null ) throw new IllegalStateException("id "+LOGOUT_ID+"が見つかりません");
		Elements a = e.getElementsByTag("a");
		if ( a == null ) throw new IllegalStateException("ログアウト用のaタグが見つかりません");
		String pathquery = a.first().attr("href");
		
		URI uri = HttpUtil.createURISafety(
						baseUri.getScheme()
						, baseUri.getAuthority()
						, pathquery
						);
		DocumentGetExecuter executer = new DocumentGetExecuter(uri, client, "logout");
		Document d = executer.execute();
		log.finest("logout response="+d.html());
	}

	@SuppressWarnings("static-access")
	@Override
	protected Options getOptions() {
		Options options = new Options();
		Option out = new OutDirOption(false);options.addOption(out);
		options.addOption(OptionBuilder.hasArg(true).withArgName("net answer id")
				.isRequired(true).withDescription("NetアンサーID")
				.create("id"));
		Option password = new PasswordOption(true); options.addOption(password);
		return options;
	}

	@Override
	protected void setParams(CommandLine cmd) {
		userId = cmd.getOptionValue("id");
		this.password = cmd.getOptionValue(PasswordOption.OPT);
		outDir = new File(cmd.getOptionValue(OutDirOption.OPT, DEFAULT_MEISAI_DIRNAME));
	}


	/* (non-Javadoc)
	 * @see name.marz.to.go.ahg.core.AbstractMain#finish()
	 */
	@Override
	protected void finish() {
		super.finish();
		// 終了処理
		client.getConnectionManager().shutdown();
	}
}
